package com.example.demo;

// 导入ArrayList类，用于存储动物对象集合

import java.util.ArrayList;
// 导入Scanner类，用于读取控制台用户输入
import java.util.Scanner;

// 定义动物行为接口，规范所有动物必须实现的行为方法（体现接口"行为规范"特性）
interface AnimalBehavior {
    // 抽象方法：动物发声（接口方法默认public abstract，无需显式声明）
    void makeSound();

    // 抽象方法：动物移动（所有实现类需重写此方法，保证行为一致性）
    void move();
}

// 定义抽象动物类，封装所有动物的共性属性与方法（体现抽象类"部分抽象+代码复用"特性）
// 实现AnimalBehavior接口，强制子类实现接口的抽象方法
abstract class AbstractAnimal implements AnimalBehavior {
    // 封装动物编号：private修饰，仅本类可直接访问（体现封装性）
    private String animalId;
    // 封装动物名称：private修饰，通过getter/setter方法访问
    private String name;
    // 封装动物年龄：private修饰，通过setter添加合法性校验
    private int age;

    // 静态变量：统计动物总数（static修饰，属于类，所有对象共享，不依赖对象存在）
    public static int totalAnimalCount = 0;
    // final常量：动物所属园区（final修饰，赋值后不可修改，确保园区信息固定）
    public final String CAMPUS_AREA = "郑州软件职业技术学院校园";

    // 带参构造方法：创建动物对象时初始化编号、名称、年龄（保证属性完整性）
    public AbstractAnimal(String animalId, String name, int age) {
        // 给动物编号赋值
        this.animalId = animalId;
        // 给动物名称赋值
        this.name = name;
        // 调用setAge方法，复用年龄合法性校验逻辑（避免代码重复）
        setAge(age);
        // 每创建一个动物对象，总数加1（静态变量共享性体现，统计所有动物数量）
        AbstractAnimal.totalAnimalCount++;
    }

    // 抽象方法：展示动物详细信息（抽象类需包含抽象方法，强制子类实现个性化展示逻辑）
    public abstract void showInfo();

    // getter方法：获取动物编号（对外提供安全访问入口，不直接暴露private属性）
    public String getAnimalId() {
        return animalId;
    }

    // getter方法：获取动物名称
    public String getName() {
        return name;
    }

    // setter方法：设置动物名称（添加非空校验，增强数据安全性）
    public void setName(String name) {
        // 判断输入的名称是否为空或仅空格
        if (name == null || name.trim().isEmpty()) {
            // 提示名称不能为空
            System.out.println("动物名称不能为空！");
            // 退出方法，不执行后续赋值
            return;
        }
        // 名称合法时赋值
        this.name = name;
    }

    // getter方法：获取动物年龄
    public int getAge() {
        return age;
    }

    // setter方法：设置动物年龄（添加范围校验，确保年龄合理）
    public void setAge(int age) {
        // 判断年龄是否在1-20之间（符合校园动物常见年龄范围）
        if (age < 1 || age > 20) {
            // 提示年龄不合法，默认设为1岁
            System.out.println("动物年龄需在1-20之间，已默认设为1岁！");
            // 赋值默认年龄
            this.age = 1;
        } else {
            // 年龄合法时赋值
            this.age = age;
        }
    }
}

// 定义狗类，继承AbstractAnimal抽象类（体现继承"代码复用"特性，子类获取父类属性和方法）
class Dog extends AbstractAnimal {
    // 狗类特有属性：品种（private修饰，仅狗类可访问，体现子类个性化属性）
    private String breed;

    // 狗类带参构造方法：初始化父类共性属性和子类特有属性
    public Dog(String animalId, String name, int age, String breed) {
        // 调用父类AbstractAnimal的带参构造方法，初始化编号、名称、年龄（必须放在子类构造第一行）
        super(animalId, name, age);
        // 给狗的品种赋值
        this.breed = breed;
    }

    // 重写父类抽象方法：展示狗的详细信息（子类必须实现父类抽象方法，体现多态前提）
    @Override
    public void showInfo() {
        // 打印狗的信息标题
        System.out.println("=== 狗的详细信息 ===");
        // 调用父类final常量CAMPUS_AREA，获取园区信息（不可修改）
        System.out.println("园区：" + super.CAMPUS_AREA);
        // 调用父类getter方法，获取动物编号（不直接访问private属性）
        System.out.println("编号：" + super.getAnimalId());
        // 调用父类getter方法，获取动物名称
        System.out.println("名称：" + super.getName());
        // 调用父类getter方法，获取动物年龄
        System.out.println("年龄：" + super.getAge() + "岁");
        // 打印狗的特有属性：品种
        System.out.println("品种：" + this.breed);
    }

    // 重写接口方法：狗的发声行为（个性化实现，体现多态"同一行为不同表现"）
    @Override
    public void makeSound() {
        // 打印狗的发声内容（结合狗的名称，增强交互性）
        System.out.println(super.getName() + "（狗）：汪汪汪！");
    }

    // 重写接口方法：狗的移动行为（个性化实现）
    @Override
    public void move() {
        // 打印狗的移动方式（符合狗的行为特征）
        System.out.println(super.getName() + "（狗）：四条腿快速奔跑！");
    }

    // 狗类特有方法：接飞盘（子类扩展父类没有的功能，体现子类个性化行为）
    public void catchFrisbee() {
        // 打印狗接飞盘的行为
        System.out.println(super.getName() + "（狗）：成功接住飞盘，好开心！");
    }
}

// 定义猫类，继承AbstractAnimal抽象类（Java单继承特性，一个类仅能直接继承一个父类）
class Cat extends AbstractAnimal {
    // 猫类特有属性：毛色（private修饰，仅猫类可访问，体现子类个性化属性）
    private String furColor;

    // 猫类带参构造方法：初始化父类共性属性和子类特有属性
    public Cat(String animalId, String name, int age, String furColor) {
        // 调用父类构造方法，初始化编号、名称、年龄
        super(animalId, name, age);
        // 给猫的毛色赋值
        this.furColor = furColor;
    }

    // 重写父类抽象方法：展示猫的详细信息（多态前提：方法重写）
    @Override
    public void showInfo() {
        // 打印猫的信息标题（换行符增强可读性）
        System.out.println("\n=== 猫的详细信息 ===");
        // 获取父类园区常量
        System.out.println("园区：" + super.CAMPUS_AREA);
        // 获取父类动物编号
        System.out.println("编号：" + super.getAnimalId());
        // 获取父类动物名称
        System.out.println("名称：" + super.getName());
        // 获取父类动物年龄
        System.out.println("年龄：" + super.getAge() + "岁");
        // 打印猫的特有属性：毛色
        System.out.println("毛色：" + this.furColor);
    }

    // 重写接口方法：猫的发声行为（个性化实现，与狗的发声区分）
    @Override
    public void makeSound() {
        // 打印猫的发声内容
        System.out.println(super.getName() + "（猫）：喵喵喵！");
    }

    // 重写接口方法：猫的移动行为（个性化实现，符合猫的行为特征）
    @Override
    public void move() {
        // 打印猫的移动方式
        System.out.println(super.getName() + "（猫）：轻盈地跳跃前进！");
    }

    // 猫类特有方法：爬树（子类扩展父类没有的功能）
    public void climbTree() {
        // 打印猫爬树的行为
        System.out.println(super.getName() + "（猫）：飞快地爬上了梧桐树！");
    }
}

// 动物管理系统主类（程序入口，包含main方法）
public class AnimalManagementSystem {
    // main方法：程序入口点，执行系统核心逻辑
    public static void main(String[] args) {
        // 创建ArrayList集合，存储AbstractAnimal类型对象（父类引用存子类对象，体现多态）
        ArrayList<AbstractAnimal> animalList = new ArrayList<>();
        // 创建Scanner对象，用于读取用户在控制台的输入
        Scanner scanner = new Scanner(System.in);
        // 循环控制变量：true表示系统运行，false表示退出系统（控制主菜单循环）
        boolean isRunning = true;

        // 系统主菜单循环：只要isRunning为true，就持续显示菜单
        while (isRunning) {
            // 打印系统标题（换行符增强可读性）
            System.out.println("\n===== 校园动物管理系统 =====");
            // 打印功能菜单1：添加动物
            System.out.println("1. 添加动物（狗/猫）");
            // 打印功能菜单2：查看所有动物信息
            System.out.println("2. 查看所有动物信息");
            // 打印功能菜单3：调用动物行为
            System.out.println("3. 调用动物行为");
            // 打印功能菜单4：查看动物总数
            System.out.println("4. 查看动物总数");
            // 打印功能菜单5：退出系统
            System.out.println("5. 退出系统");
            // 提示用户输入操作编号
            System.out.print("请输入操作编号（1-5）：");

            // 读取用户输入的整数（操作编号）
            int choice = scanner.nextInt();
            // 吸收输入缓冲区中的换行符（避免后续nextLine()读取时获取空值）
            scanner.nextLine();

            // switch分支：根据用户选择的编号执行对应功能
            switch (choice) {
                //  case1：执行添加动物功能
                case 1:
                    // 调用addAnimal方法，传入动物集合和scanner对象（实现添加逻辑）
                    addAnimal(animalList, scanner);
                    // 跳出switch分支
                    break;
                //  case2：执行查看所有动物信息功能
                case 2:
                    // 调用showAllAnimals方法，传入动物集合（实现查看逻辑）
                    showAllAnimals(animalList);
                    // 跳出switch分支
                    break;
                //  case3：执行调用动物行为功能
                case 3:
                    // 调用showAnimalBehaviors方法，传入动物集合（实现行为展示逻辑）
                    showAnimalBehaviors(animalList);
                    // 跳出switch分支
                    break;
                //  case4：执行查看动物总数功能
                case 4:
                    // 打印动物总数标题
                    System.out.println("\n===== 动物总数 =====");
                    // 访问父类静态变量totalAnimalCount，获取动物总数（无需创建对象）
                    System.out.println("当前校园动物总数：" + AbstractAnimal.totalAnimalCount + "只");
                    // 跳出switch分支
                    break;
                //  case5：执行退出系统功能
                case 5:
                    // 打印退出提示
                    System.out.println("感谢使用，系统已退出！");
                    // 将循环控制变量设为false，结束主菜单循环
                    isRunning = false;
                    // 跳出switch分支
                    break;
                //  default：处理无效输入（用户输入编号不在1-5之间）
                default:
                    // 打印输入错误提示
                    System.out.println("输入有误，请重新输入！");
            }
        }

        // 关闭Scanner对象，释放输入资源（避免资源泄漏）
        scanner.close();
    }

    // 自定义方法：添加动物（参数1：存储动物的集合；参数2：读取输入的scanner对象）
    public static void addAnimal(ArrayList<AbstractAnimal> animalList, Scanner scanner) {
        // 打印添加动物标题
        System.out.println("\n===== 添加动物 =====");
        // 提示用户选择动物类型（1.狗 2.猫）
        System.out.print("请选择动物类型（1.狗 2.猫）：");
        // 读取用户选择的动物类型编号
        int animalType = scanner.nextInt();
        // 吸收换行符（避免后续读取名称时获取空值）
        scanner.nextLine();

        // 提示用户输入动物编号
        System.out.print("请输入动物编号：");
        // 读取动物编号
        String animalId = scanner.nextLine();
        // 提示用户输入动物名称
        System.out.print("请输入动物名称：");
        // 读取动物名称
        String name = scanner.nextLine();
        // 提示用户输入动物年龄（并说明范围）
        System.out.print("请输入动物年龄（1-20）：");
        // 读取动物年龄
        int age = scanner.nextInt();
        // 吸收换行符
        scanner.nextLine();

        // 判断动物类型：1表示狗
        if (animalType == 1) {
            // 提示用户输入狗的品种
            System.out.print("请输入狗的品种：");
            // 读取狗的品种
            String breed = scanner.nextLine();
            // 创建Dog对象，添加到动物集合中（父类引用存子类对象，体现多态）
            animalList.add(new Dog(animalId, name, age, breed));
            // 提示狗添加成功
            System.out.println("狗添加成功！");
        }
        // 判断动物类型：2表示猫
        else if (animalType == 2) {
            // 提示用户输入猫的毛色
            System.out.print("请输入猫的毛色：");
            // 读取猫的毛色
            String furColor = scanner.nextLine();
            // 创建Cat对象，添加到动物集合中
            animalList.add(new Cat(animalId, name, age, furColor));
            // 提示猫添加成功
            System.out.println("猫添加成功！");
        }
        // 动物类型不是1或2（无效选择）
        else {
            // 提示动物类型选择有误，添加失败
            System.out.println("动物类型选择有误，添加失败！");
        }
    }

    // 自定义方法：查看所有动物信息（参数：存储动物的集合）
    public static void showAllAnimals(ArrayList<AbstractAnimal> animalList) {
        // 打印查看动物信息标题
        System.out.println("\n===== 所有动物信息 =====");
        // 判断集合是否为空（没有添加任何动物）
        if (animalList.isEmpty()) {
            // 提示暂无动物数据
            System.out.println("当前暂无动物数据，请先添加动物！");
            // 退出方法，不执行后续遍历
            return;
        }
        // 增强for循环：遍历动物集合（父类引用遍历子类对象，体现多态）
        for (AbstractAnimal animal : animalList) {
            // 调用showInfo方法：实际执行子类（Dog/Cat）重写后的方法（多态核心体现）
            animal.showInfo();
        }
    }

    // 自定义方法：调用所有动物行为（参数：存储动物的集合）
    public static void showAnimalBehaviors(ArrayList<AbstractAnimal> animalList) {
        // 打印动物行为展示标题
        System.out.println("\n===== 动物行为展示 =====");
        // 判断集合是否为空
        if (animalList.isEmpty()) {
            // 提示暂无动物数据
            System.out.println("当前暂无动物数据，请先添加动物！");
            // 退出方法
            return;
        }
        // 增强for循环：遍历动物集合
        for (AbstractAnimal animal : animalList) {
            // 调用makeSound方法：执行子类重写的发声逻辑（多态体现）
            animal.makeSound();
            // 调用move方法：执行子类重写的移动逻辑（多态体现）
            animal.move();
            // instanceof判断：当前动物是否为Dog类型（避免转型错误）
            if (animal instanceof Dog) {
                // 向下转型：将AbstractAnimal类型转为Dog类型（才能调用Dog特有方法）
                Dog dog = (Dog) animal;
                // 调用Dog特有方法catchFrisbee
                dog.catchFrisbee();
            }
            // instanceof判断：当前动物是否为Cat类型
            else if (animal instanceof Cat) {
                // 向下转型：将AbstractAnimal类型转为Cat类型
                Cat cat = (Cat) animal;
                // 调用Cat特有方法climbTree
                cat.climbTree();
            }
        }
    }
}